#pragma once

#include <iostream>
#include <unistd.h>
#include <wait.h>
#include <sys/types.h>
#include <fcntl.h>

#include "../comm/log.hpp"
#include "../comm/util.hpp"

namespace ns_compiler
{
    //引入路径拼接和日志功能
    using namespace ns_util;
    using namespace ns_log;

    class Compiler//编译器
    {
    public:
      Compiler(){}
      ~Compiler(){}
    public:
      static bool Compile(const std::string &file_name)
      {
        pid_t pid=fork();
        if(pid<0)
        {
          LOG(ERROR)<<"fork error";
          return false;
        }
        else if(pid==0)//子进程
        {
            umask(0);//设置权限掩码
            
            int error_fd=open(PathUtil::CompilerError(file_name).c_str(),O_CREAT|O_WRONLY,0644);//创建用于保存输出错误的文件
            if(error_fd<0)
            {
              LOG(WARNING)<<"打开或创建.compiler_error文件失败\n";
              exit(1);
            }
            dup2(error_fd,2);//将标准错误输出重定向到文件
            
            //g++ -o file_name.exe file_name.cpp -std=c++11
            execlp("g++","g++","-o",PathUtil::Exe(file_name).c_str()/*.exe*/,
                   PathUtil::Src(file_name).c_str()/*.cpp*/,"-D"/*预处理宏*/,
                   "COMPILER_ONLINE","-std=c++11",nullptr);//编译

            LOG(ERROR)<<"启动编译器失败";
            exit(2);
        }
        else//父进程
        {
            waitpid(pid,nullptr,0);
            if(FileUtil::IsFileExists(PathUtil::Exe(file_name)))
            {
                LOG(INFO)<<PathUtil::Src(file_name)<<"编译成功";
                return true;
            }
            LOG(ERROR)<<"编译失败，没有生成可执行程序";
            return false;
        }

      }
    };
}